package cn.itcast.nems.job;

import java.util.List;
import java.util.Objects;

import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;

import cn.hutool.core.lang.Assert;
import cn.itcast.nems.common.account.AccountHolder;
import cn.itcast.nems.common.account.AccountInfo;
import cn.itcast.nems.common.tenant.TenantInfo;
import cn.itcast.nems.common.tenant.TenantInfoHolder;
import cn.itcast.nems.employee.dao.entity.Employee;
import cn.itcast.nems.employee.service.EmployeeService;
import cn.itcast.nems.journal.scheduler.BatchImportJournalTransferHandler;
import cn.itcast.nems.journal.scheduler.JournalBatchImportProcessState;
import cn.itcast.nems.journal.scheduler.JournalTransferBatchImportService;
import cn.itcast.nems.studentrecord.dao.entity.JournalTransferBatchImport;
import cn.itcast.nems.studentrecord.dao.entity.JournalTransferType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 凭单批量入库处理
 * 转班（同学科、其他转班）、转待定、待定学员、休学、休学学员
 * </p>
 **/
@Slf4j
@Component
@RequiredArgsConstructor
public class BatchImportJournalTransferJob {
    private final EmployeeService employeeService;
    private final JournalTransferBatchImportService journalTransferBatchImportService;
    private final BatchImportJournalTransferHandler importJournalTransferHandler;

    @XxlJob("BatchImportJournalTransfer")
    public ReturnT<String> batchImport(String journalType) {
        log.debug("转班/休学/待定批量导入任务-开始！");
        int taskCount = 0; // 任务条数
        
        try {
            // 默认租户
            TenantInfoHolder.setTenantInfo(new TenantInfo(TenantInfo.DEFAULT_TENANT_ID, TenantInfo.DEFAULT_SUBTENANT_ID));
            
            // 获取任务列表
            List<JournalTransferBatchImport> list = journalTransferBatchImportService.list(journalType);
            if (list == null || list.isEmpty()) {
                return new ReturnT<>("OK");
            }
            taskCount = list.size();
            
            // 单个任务导入
            list.forEach(this::singleImportTask);
        } finally {
            TenantInfoHolder.clear();
            AccountHolder.clear();
        }
        
        log.debug("转班/休学/待定批量导入任务-完成！执行单条任务总数：{}", taskCount);
        return new ReturnT<>("OK");
    }
    
    /**
     * 
     * 功能描述：处理单条导入任务
     *
     * @param task 单条任务
     * 
     * @author 刘曙
     *
     * @since 2024年3月17日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    public void singleImportTask(JournalTransferBatchImport task) {
        String operatorType = task.getOperatorType().trim();
        
        try {
            // 发起人登录
            setAccount(task.getCreatorEmail());
            
            switch (operatorType) {
                case "同学科转班":
                    importJournalTransferHandler.importTransfer(task, JournalTransferType.EXCHANGE);
                    break;
                case "其他转班":
                    importJournalTransferHandler.importTransfer(task, JournalTransferType.TRANSFER);
                    break;
                case "待定班":
                    importJournalTransferHandler.importTransfer(task, JournalTransferType.DELAY);
                    break;
                case "待定班学员（转确定）":
                    importJournalTransferHandler.importDelay(task);
                    break;
                case "休学":
                    importJournalTransferHandler.importSuspended(task);
                    break;
                case "休学学员（休学归来）":
                    importJournalTransferHandler.importSuspended(task);
                    break;
                default:
                    throw new IllegalArgumentException("未知的操作类型值: " + operatorType);
            }
        } catch (Exception e) {
            singleImportTaskFaild(task, e);
        }
    }
    
    /**
     * 发起人登录
     *
     * @param email
     */
    private void setAccount(String creator) {
        if (!StringUtils.hasText(creator)) {
            return;
        }
        
        // 通过发起人姓名获取用户
        List<Employee> employees = employeeService.findByName(creator);
        Assert.isTrue(!CollectionUtils.isEmpty(employees) && employees.size()==1, "发起人【{}】不正确，找不到或找到多个员工用户！", creator);
        
        // 登录
        Employee employee = employees.get(0);
        AccountHolder.setAccountInfo(new AccountInfo(employee.getEmail(), employee.getName(), employee.getJobNumber(), ""));
    }
    
    /**
     * 
     * 功能描述：获取任务执行结束以后的任务执行次数
     *
     * @param task 当前任务
     * @return 任务结束以后的执行次数
     * 
     * @author 刘曙
     *
     * @since 2024年3月17日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    private int getProcessRetriesNumber(final JournalTransferBatchImport task) {
        int currentNumber = Objects.isNull(task.getProcessRetriesNumber()) ? 0 : task.getProcessRetriesNumber(); 
        return currentNumber + 1;
    }
    
    /**
     * 
     * 功能描述：单条任务失败处理！
     *
     * @param task 单条导入任务
     * @param e 异常
     * 
     * @author 刘曙
     *
     * @since 2024年3月17日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    private void singleImportTaskFaild(final JournalTransferBatchImport task, final Throwable e) {
        String message = e.getMessage().substring(0, e.getMessage().length()>200 ? 200: e.getMessage().length());
        int processRetriesNumber = getProcessRetriesNumber(task);
        journalTransferBatchImportService.update(task.getId(), 
                                                 JournalBatchImportProcessState.FAILED.name(), 
                                                 "导入凭单失败！失败原因：" + message, processRetriesNumber, "");
    }
}
